/*
 * TANAndAccountManagementWindow.java
 * 
 * Main class of the graphical client for TAN and Account Management.
 * 
 * Copyright (C) 2008 Fraunhofer SCAI, Germany
 * All rights reserved
 * 
 * https://gforge.beingrid.eu/gf/project/scailm
 */

package de.fraunhofer.scai.lm.gui;

import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import org.apache.axis2.AxisFault;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;


import com.swtdesigner.SWTResourceManager;

import de.fraunhofer.scai.lm.LMProperties;
import de.fraunhofer.scai.lm.accountservice.client.AccountServiceClient;
import de.fraunhofer.scai.lm.accountservice.client.gen.AccountServiceStub;
import de.fraunhofer.scai.lm.tanservice.client.TANServiceClient;
import de.fraunhofer.scai.lm.tanservice.client.gen.TANServiceStub;

/**
 * This class is the graphical entry point to the TAN and Account Management.
 * 
 * @author Bea Hornef
 * @author Yona Raekow
 */
public class TANAndAccountManagementWindow extends ApplicationWindow {

	/**
	 * Logger for the TANAndAccountManagementWindow class.
	 */
	static Logger logger = Logger
			.getLogger(TANAndAccountManagementWindow.class);

	/********************************************************** GUI Attributes *********************************/

	/**
	 * Contains LogoContainer and MainContainer.
	 */
	private Composite myOverAllContainer;

	/**
	 * At the beginning contains the GUI elements for login. After login
	 * contains management GUI elements.
	 */
	private Composite myMainContainer;

	/*
	 * Several GUI components
	 */
	private Shell myShell;

	private Button myBlockButton, myUnblockButton;

	private Text myTanEmailText;

	private Combo myAccountCombo;

	private Text myTanListNumberText;

	private Text myNumberOfTansText;

	private Text myUnusedTansText;

	private Text myUsedTansText;

	private Text myCostsText;

	private Label myOverviewLabel;

	private Table myCostsPerFeatureTable;

	private static final String[] myCostsPerFeatureTitles = { "Feature",
			"Usage (CPU hours)", "Cost" };
	private static final String[] myOverviewTitles = { "Account", "Costs (€)" };

	/********************************************************** Functional Attributes **************************/


	/**
	 * Warning message if the user tries to do actions, without having an
	 * account selected.
	 */
	private static final String MESSAGE_ACCOUNT = "Please select an account first!";

	/**
	 * Session for the login process.
	 */
	// private Session mySession;
	/**
	 * Distinguished name, i.e. the subject string from the X509 certificate
	 */
	// private String myDistinguishedName;
	/**
	 * String for the myUserName
	 */
	private String myUserName;

	/**
	 * String for the myOrganization,
	 */
	private String myOrganization;
	
	private String myBillingAccount;

	/**
	 * String for the myEmail, obtained via the web service
	 */
	private String myEmail;

	/**
	 * String for the myPassword, i.e. the the Password for the certificate
	 */
	private String myPassword;

	/**
	 * True if log-in was successful. False otherwise.
	 */
	private boolean myIsLoggedIn;

	/**
	 * Text field for the password.
	 */
	private Text myPasswordText;

	private Text myOrganizationText;

	/**
	 * Table containing all accounts.
	 */
	private Hashtable<String, Account> myAccountTable = new Hashtable<String, Account>();

	private Integer myNumberOfTANs;

	private TANServiceClient myTANClient;

	private AccountServiceClient myAccountClient;

	private static LMProperties myProperties;

	private Table myOverviewTable;

	private Text myBillingAccountText;


	/**
	 * Initialize the application window.
	 */
	public TANAndAccountManagementWindow() {
		super((Shell) null);
		myIsLoggedIn = false;
		myNumberOfTANs = null;

		/*
		 * Load properties.
		 */
		myProperties = new LMProperties();
		myProperties.load("config.txt");
		System.setProperty("javax.net.ssl.trustStore", myProperties.getTrustStore());
		//System.setProperty("javax.net.ssl.trustStorePassword", myProperties.getTrustStorePassword());

		/*
		 * Get the user name
		 */

		myUserName = "";

		/*
		 * Clients for TAN and Account Management.
		 */
		myTANClient = createTANClient();
		myAccountClient = createAccountClient();

	}

	/*
	 * GUI methods.
	 */

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jface.window.ApplicationWindow#configureShell(org.eclipse
	 * .swt.widgets.Shell)
	 */
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		myShell = newShell;
		newShell.setText("TAN- and Account-Management");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.window.ApplicationWindow#close()
	 */
	public boolean close() {
		// when the user closes the window, enforce a logout.
		if (this.myIsLoggedIn) {
			logoutUser();
		}
		return super.close();
	}

	/**
	 * Create contents of the application window.
	 * 
	 * @param composite
	 *            Parent composite of the content.
	 */
	@Override
	protected Control createContents(Composite composite) {
		// Container that holds all sub-containers.
		myOverAllContainer = new Composite(composite, SWT.NONE);
		RowLayout rowLayout = new RowLayout();
		rowLayout.fill = true;
		rowLayout.type = SWT.VERTICAL;

		myOverAllContainer.setLayout(rowLayout);

		// 2 main GUI containers.
		createLogoContainer(myOverAllContainer);
		createLoginContainer(myOverAllContainer);

		myOverAllContainer.pack();
		return myOverAllContainer;
	}

	/**
	 * Create container for the partner logos.
	 * 
	 * @param composite
	 *            Parent composite of the LogoContainer.
	 */
	private void createLogoContainer(Composite composite) {

		Composite container = new Composite(composite, SWT.NONE);
		container.setLayout(new GridLayout(2, true));

		final Label scaiLabel = new Label(container, SWT.NONE);
		scaiLabel.setLayoutData(new GridData());
		scaiLabel.setImage(SWTResourceManager.getImage(
				TANAndAccountManagementWindow.class, "images/SCAI-Logo.gif"));

		final Label tsystemsLabel = new Label(container, SWT.NONE);
		tsystemsLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END
				| GridData.GRAB_HORIZONTAL));
		tsystemsLabel.setImage(SWTResourceManager.getImage(
				TANAndAccountManagementWindow.class,
				"images/T-Systems-Logo.jpg"));
	}

	/**
	 * Create container for log-in information.
	 * 
	 * @param composite
	 *            Parent composite of the LoginContainer.
	 */
	private void createLoginContainer(Composite composite) {

		myMainContainer = new Composite(composite, SWT.NONE);
		myMainContainer.setLayout(new GridLayout(1, false));

		// Label informing the user to authenticate himself.
		final Label welcomeLabel = new Label(myMainContainer, SWT.HORIZONTAL);
		welcomeLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true,
				false, 1, 10));
		welcomeLabel.setText("Please enter your billing account and password.");

		// Container for log-in infos.
		Composite inputContainer = new Composite(myMainContainer, SWT.NONE);    
		inputContainer.setLayout(new GridLayout(2, false));
		GridData inputContainerGridData = new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 10);
		inputContainerGridData.widthHint = 250;
		inputContainer.setLayoutData(inputContainerGridData);

		final Label billingAccountLabel = new Label(inputContainer, SWT.NONE);
		billingAccountLabel.setText("Billing Account:");

		myBillingAccountText= new Text(inputContainer, SWT.BORDER);
		myBillingAccountText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		myBillingAccountText.setEditable(true);

		myBillingAccountText.setToolTipText("Enter billing account.");
		myBillingAccountText.setFocus();

		
		final Label passwordLabel = new Label(inputContainer, SWT.NONE);
		passwordLabel.setText("Password:");

		myPasswordText = new Text(inputContainer, SWT.PASSWORD | SWT.BORDER);
		myPasswordText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		// Button to get accounts for the provided user name.
		final Button loginButton = new Button(myMainContainer, SWT.NONE);
		loginButton.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true,
				true, 1, 7));
		loginButton.setText("Login");
		myShell.setDefaultButton(loginButton);

		// Verifies the password.
		loginButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (myPasswordText.getText().trim().length() == 0) {
					logger.info("Empty password");
					MessageDialog.openInformation(myShell, "Empty password",
							"Please enter a valid password!");
					return;
				}
				/*
				 * try { myIsLoggedIn = mySession
				 * .authenticateAgainstCertificate(myPasswordText .getText()); }
				 * catch (IOException e1) {
				 * logger.error("error occured while reading the certificate " +
				 * e1.getStackTrace()); } catch (GeneralSecurityException e1) {
				 * logger.error("Password Invalid " + e1.getStackTrace()); } if
				 * (!myIsLoggedIn) { MessageDialog.openInformation(myShell,
				 * "Password Invalid", "Please enter a valid password!");
				 * return; }
				 */

				// If password is valid: read the accounts.
				myPassword = myPasswordText.getText();
				myBillingAccount = myBillingAccountText.getText();
				if(readAccounts()){
					createManagementContainer(myOverAllContainer);
					myOverAllContainer.getParent().pack();
				}else{
					logger.error("Password Invalid ");  
					MessageDialog.openInformation(myShell,
					 "Password Invalid", "Please enter a valid password!");
					  return; 
				}
			};
		});
	}

	/**
	 * Contains GUI elements for account and TAN management.
	 * 
	 * @param composite
	 *            Parent composite of the management container.
	 */
	private void createManagementContainer(Composite composite) {
		
		myMainContainer.dispose();
		myMainContainer = new Composite(composite, SWT.NONE);
		myMainContainer.setLayout(new GridLayout(1, true));

		final Composite synchronizeContainer = new Composite(myMainContainer, SWT.NONE);
		synchronizeContainer.setLayout(new GridLayout(2, false));
		synchronizeContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		// Contains user name and account name combo.
		final Composite nameContainer = new Composite(synchronizeContainer, SWT.NONE);
		GridLayout nameLayout = new GridLayout(2, false);
		nameLayout.marginTop = 10;
		nameLayout.marginBottom = 10;
		nameContainer.setLayout(nameLayout);
		nameContainer.setLayoutData(new GridData (SWT.FILL, SWT.LEFT, true, false));

		final Label userNameLabel = new Label(nameContainer, SWT.NONE);
		userNameLabel.setText("Username: ");

		final Text tanUserNameText = new Text(nameContainer, SWT.NONE);
		tanUserNameText.setEditable(false);
		tanUserNameText.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true,
				false));
		tanUserNameText.setText(myUserName);

		final Label organizationLabel = new Label(nameContainer, SWT.NONE);
		organizationLabel.setText("Organization: ");

		myOrganizationText = new Text(nameContainer, SWT.NONE);
		myOrganizationText.setEditable(false);
		myOrganizationText.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true,
				false));
		myOrganizationText.setText(myOrganization);
		
		final Label emailLabel = new Label(nameContainer, SWT.NONE);
		emailLabel.setText("Email: ");
		myTanEmailText = new Text(nameContainer, SWT.NONE);
		myTanEmailText.setEditable(false);
		myTanEmailText.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true,
				false));
		// 7.4.09 for YONA: email address to be set here
	
		myTanEmailText.setText(myEmail);
		
		new Label(nameContainer, SWT.NONE);
		new Label(nameContainer, SWT.NONE);

		final Label accountLabel = new Label(nameContainer, SWT.NONE);
		accountLabel.setText("Account: ");
		accountLabel.setToolTipText("Please select an existing account");
		myAccountCombo = new Combo(nameContainer, SWT.READ_ONLY);
		
		for (Enumeration<String> en = myAccountTable.keys(); en
				.hasMoreElements();) {
			String key = en.nextElement();
			myAccountCombo.add(key);
		}
		
		myAccountCombo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false,
				false));
		myAccountCombo.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				actualizeAccountTexts(myAccountTable.get(myAccountCombo
						.getText()));
			};
		});	
		//nameContainer.pack();
		
		final Composite synchronizeButtonContainer = new Composite(synchronizeContainer, SWT.NONE);
		GridLayout buttonLayout = new GridLayout(1, false);
		buttonLayout.marginTop = 10;
		buttonLayout.marginBottom = 10;
		synchronizeButtonContainer.setLayout(buttonLayout);
		synchronizeButtonContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		        

		final Button synchronizeButton = new Button(synchronizeButtonContainer, SWT.NONE);
		synchronizeButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_END |
													 GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
		synchronizeButton.setText("Synchronize with Database");

        synchronizeButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
            	myAccountCombo.removeAll();
            	if(readAccounts()){
            		for (Enumeration<String> en = myAccountTable.keys(); en
            		.hasMoreElements();) {
            			String key = en.nextElement();
            			myAccountCombo.add(key);
            		}
            		myAccountCombo.select(0);
            		actualizeAccountTexts(myAccountTable.get(myAccountCombo.getText()));
            	}
                
            };
          });
              
		// Contains two tabs: TAN and account management.
		final TabFolder tabFolder = new TabFolder(myMainContainer, SWT.BORDER);
		tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				1, 5));
		tabFolder.setEnabled(true);

		TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setText("TAN Management");
		tabItem.setControl(createTANTabItem(tabFolder));

		tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setText("License Account Management");
		tabItem.setControl(createAccountTabItem(tabFolder));

		tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setText("Billing Account Overview");
		tabItem.setControl(createOverviewTabItem(tabFolder));

		//tabFolder.pack();
		tabFolder.setSelection(0);

		//default selection
		myAccountCombo.select(0);
        actualizeAccountTexts(myAccountTable.get(myAccountCombo.getText()));
		
		// Button to log-out.
		final Button logoutButton = new Button(myMainContainer, SWT.NONE);
		logoutButton.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true,
				false, 1, 7));
		logoutButton.setText("Logout");
		myShell.setDefaultButton(logoutButton);

		logoutButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				myShell.close();
			};
		});
		
		myMainContainer.pack();
		myMainContainer.getParent().pack();
		myOverAllContainer.getParent().redraw();

	}

	/**
	 * @param composite
	 *            Parent composite of the TAN tab.
	 * @return Composite of the TAN tab.
	 */
	private Composite createTANTabItem(Composite composite) {
		// Contains button container and info container.
		final Composite tanContainer = new Composite(composite, SWT.NONE);
		final GridLayout gridLayout = new GridLayout();
		gridLayout.marginBottom = 10;
		gridLayout.marginRight = 10;
		gridLayout.marginLeft = 10;
		gridLayout.marginTop = 20;
		gridLayout.numColumns = 1;
		tanContainer.setLayout(gridLayout);

		// Contains 3 buttons: create button, block button, unblock button.
		Composite buttonContainer = new Composite(tanContainer, SWT.NONE);
		buttonContainer.setLayout(new GridLayout(3, false));

		final Button createButton = new Button(buttonContainer, SWT.FLAT);
		createButton.setToolTipText("Create a new TAN list");
		createButton.setImage(SWTResourceManager.getImage(
				TANAndAccountManagementWindow.class, "images/create_tan.gif"));

		createButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				final String actualSelection = myAccountCombo.getText();
				if (actualSelection.isEmpty()) {
					MessageDialog.openInformation(getShell(), "Info",
							MESSAGE_ACCOUNT);
					return;
				}
				TanListDialog tanListDialog = new TanListDialog(myAccountTable
						.get(actualSelection).getTanListNumber(),
						myOverAllContainer.getShell());
				tanListDialog.open();
				myNumberOfTANs = tanListDialog.getNumberOfTANs();
				logger.debug("Number of TANS" + myNumberOfTANs);
				if (myNumberOfTANs != null) {
					final Account actualAccount = myAccountTable
							.get(actualSelection);
					createTANList(actualAccount, myNumberOfTANs);
					actualizeAccountTexts(actualAccount);
				}
				tanContainer.redraw();

			};
		});

		myBlockButton = new Button(buttonContainer, SWT.FLAT);
		myBlockButton.setToolTipText("Block TAN list");
		myBlockButton.setImage(SWTResourceManager.getImage(
				TANAndAccountManagementWindow.class, "images/block_tan.gif"));

		myBlockButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				final String actualSelection = myAccountCombo.getText();
				if (actualSelection.isEmpty()) {
					MessageDialog.openInformation(getShell(), "Info",
							MESSAGE_ACCOUNT);
					return;
				}
				boolean block = MessageDialog.openQuestion(myOverAllContainer
						.getShell(), "Block TAN List",
						"Do you really want to block the TAN List?");
				if (block) {
					// blockTANList(myAccountCombo.getItem(myAccountCombo.getSelectionIndex()));
					boolean successfullyBlocked = blockTANList(myAccountTable
							.get(actualSelection));
					if (successfullyBlocked) {
						myUnblockButton.setEnabled(true);
						myBlockButton.setEnabled(false);
					} else
						logger.error("Blocking TANList failed");
				}
			}
		});

		myUnblockButton = new Button(buttonContainer, SWT.FLAT);
		myUnblockButton.setToolTipText("Unblock TAN list");
		myUnblockButton.setImage(SWTResourceManager.getImage(
				TANAndAccountManagementWindow.class, "images/unblock_tan.gif"));

		myUnblockButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				final String actualSelection = myAccountCombo.getText();
				if (actualSelection.isEmpty()) {
					MessageDialog.openInformation(getShell(), "Info",
							MESSAGE_ACCOUNT);
					return;
				}
				// unblockTANList(myAccountCombo.getItem(myAccountCombo.getSelectionIndex()));
				boolean successfullyUnblocked = unblockTANList(myAccountTable
						.get(actualSelection));
				if (successfullyUnblocked) {
					myBlockButton.setEnabled(true);
					myUnblockButton.setEnabled(false);
				} else
					logger.error("Unblocking TAN failed");

			}
		});

		/*
		 * Contains labels and corresponding text fields informing about the TAN
		 * status of the selected account.
		 */
		Composite infoContainer = new Composite(tanContainer, SWT.NONE);
		infoContainer.setLayout(new GridLayout(2, false));
		infoContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				false));

		new Label(tanContainer, SWT.NONE);

		final Label tanlistNumberLabel = new Label(infoContainer, SWT.NONE);
		tanlistNumberLabel.setText("TAN List Number: ");

		myTanListNumberText = new Text(infoContainer, SWT.BORDER);
		myTanListNumberText.setEditable(false);
		final GridData gd_tanListNumberText = new GridData(SWT.LEFT,
				SWT.CENTER, true, false);
		gd_tanListNumberText.widthHint = 50;
		myTanListNumberText.setLayoutData(gd_tanListNumberText);

		final Label numberOfTansLabel = new Label(infoContainer, SWT.NONE);
		numberOfTansLabel.setText("Number of TANs:");

		myNumberOfTansText = new Text(infoContainer, SWT.BORDER);
		myNumberOfTansText.setEditable(false);
		final GridData gd_numberOfTansText = new GridData(SWT.LEFT, SWT.CENTER,
				true, false);
		gd_numberOfTansText.widthHint = 50;
		myNumberOfTansText.setLayoutData(gd_numberOfTansText);

		final Label unusedTansLabel = new Label(infoContainer, SWT.NONE);
		unusedTansLabel.setText("Unused TANs:");

		myUnusedTansText = new Text(infoContainer, SWT.BORDER);
		myUnusedTansText.setEditable(false);
		final GridData gd_unusedTansText = new GridData(SWT.LEFT, SWT.CENTER,
				true, false);
		gd_unusedTansText.widthHint = 50;
		myUnusedTansText.setLayoutData(gd_unusedTansText);

		tanContainer.pack();
		return tanContainer;
	}

	/**
	 * @param composite
	 *            Parent composite of the Account tab.
	 * @return Composite of the Account tab.
	 */
	private Composite createAccountTabItem(Composite composite) {
		// Contains button container and info container.
		final Composite accountContainer = new Composite(composite, SWT.NONE);
		final GridLayout gridLayout = new GridLayout();
		gridLayout.marginBottom = 10;
		gridLayout.marginRight = 10;
		gridLayout.marginLeft = 10;
		gridLayout.marginTop = 20;
		gridLayout.numColumns = 2;
		accountContainer.setLayout(gridLayout);

		Composite leftContainer = new Composite(accountContainer, SWT.NONE);
		final GridLayout gridLayout1 = new GridLayout();
		gridLayout1.numColumns = 1;
		leftContainer.setLayout(gridLayout1);

		// Contains 2 buttons: create account, delete account
		Composite buttonContainer = new Composite(leftContainer, SWT.NONE);
		buttonContainer.setLayout(new GridLayout(3, false));

		final Button createAccountButton = new Button(buttonContainer, SWT.NONE);
		createAccountButton.setImage(SWTResourceManager.getImage(
				TANAndAccountManagementWindow.class,
				"images/create_account.gif"));
		createAccountButton.setToolTipText("Create a new account");

		createAccountButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				AccountDialog createAccountDialog = new AccountDialog(
						myOverAllContainer.getShell(), myAccountTable);
				createAccountDialog.open();
				String newAccountName = createAccountDialog.getAccountName();
				if (newAccountName == null) {
					// cancel was pressed
					logger.debug("cancel was pressed");
					return;
				}

				String newAccountType = createAccountDialog.getAccountType();

				// Call the web service in order to create a new licenseAccount
				// with the given name
				newAccountName = myBillingAccount + "_" + newAccountName;
				if(createLicenseAccount(newAccountName, newAccountType)){
				final Account newAccount = new Account(newAccountName);
				myAccountTable.put(newAccountName, newAccount);
				myAccountCombo.add(newAccountName);
				myAccountCombo.select(myAccountCombo.indexOf(newAccountName));
				actualizeAccountTexts(newAccount);
				}
				else
					System.out.println("Cannot create account");
			};
		});

		final Button deleteAccountButton = new Button(buttonContainer, SWT.NONE);
		deleteAccountButton.setImage(SWTResourceManager.getImage(
				TANAndAccountManagementWindow.class,
				"images/delete_account.gif"));
		deleteAccountButton.setToolTipText("Delete an account");

		deleteAccountButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				final String actualSelection = myAccountCombo.getText();
				if (actualSelection.isEmpty()) {
					MessageDialog.openInformation(getShell(), "Info",
							MESSAGE_ACCOUNT);
					return;
				}

				boolean delete = MessageDialog.openQuestion(myOverAllContainer
						.getShell(), "Delete account",
						"Do you really want to delete the account "
								+ myAccountCombo.getText() + " ?");
				if (delete) {
					deleteLicenseAccount(actualSelection);
					myAccountTable.remove(actualSelection);
					myAccountCombo.remove(actualSelection);
				}
			};
		});

		/*
		 * Contains labels and corresponding text fields with information about
		 * the selected account.
		 */
		Composite infoContainer = new Composite(leftContainer, SWT.NONE);
		infoContainer.setLayout(new GridLayout(2, false));
		infoContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				false));

		final Label usedTansLabel = new Label(infoContainer, SWT.NONE);
		usedTansLabel.setText("Used TANs:");

		myUsedTansText = new Text(infoContainer, SWT.BORDER);
		myUsedTansText.setEditable(false);
		final GridData gd_usedTansText = new GridData(SWT.LEFT, SWT.CENTER,
				true, false);
		gd_usedTansText.widthHint = 50;
		myUsedTansText.setLayoutData(gd_usedTansText);

		final Label costsLabel = new Label(infoContainer, SWT.NONE);
		costsLabel.setText("Costs (€):");

		myCostsText = new Text(infoContainer, SWT.BORDER);
		myCostsText.setEditable(false);
		final GridData gd_costsText = new GridData(SWT.LEFT, SWT.CENTER, true,
				false);
		gd_costsText.widthHint = 50;
		myCostsText.setLayoutData(gd_costsText);

		Composite rightContainer = new Composite(accountContainer, SWT.NONE);
		rightContainer.setLayout(new GridLayout(1, false));
		rightContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				false));

		myCostsPerFeatureTable = new Table(rightContainer, SWT.MULTI
				| SWT.BORDER | SWT.FULL_SELECTION);
		myCostsPerFeatureTable.setLinesVisible(true);
		myCostsPerFeatureTable.setHeaderVisible(true);
		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);

		// 7.4.09 for YONA: "miloc" = most important lines of code ;-)
		// Without these instructions the scroll bars will not appear.
		data.heightHint = 120;
		data.widthHint = 400;

		myCostsPerFeatureTable.setLayoutData(data);
		// 7.4.09 for YONA : if you need more columns, just add the titles here.

		for (int i = 0; i < myCostsPerFeatureTitles.length; i++) {
			TableColumn column = new TableColumn(myCostsPerFeatureTable,
					SWT.NONE);
			column.setText(myCostsPerFeatureTitles[i]);
		}
		return accountContainer;
	}

	/**
	 * @param composite
	 *            Parent composite of the Account tab.
	 * @return Composite of the Account tab.
	 */
	private Composite createOverviewTabItem(Composite composite) {
		Composite overviewContainer = new Composite(composite, SWT.NONE);
		final GridLayout gridLayout = new GridLayout();
		gridLayout.marginBottom = 10;
		gridLayout.marginRight = 10;
		gridLayout.marginLeft = 10;
		gridLayout.marginTop = 20;
		gridLayout.numColumns = 1;
		overviewContainer.setLayout(gridLayout);

		final Label overviewLabel = new Label(overviewContainer, SWT.NONE);
		overviewLabel.setText("Overview all accounts:");

		myOverviewTable = new Table(overviewContainer, SWT.MULTI | SWT.BORDER
				| SWT.FULL_SELECTION);
		myOverviewTable.setLinesVisible(true);
		myOverviewTable.setHeaderVisible(true);
		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);

		// 7.4.09 for YONA: "miloc" = most important lines of code ;-)
		// Without these instructions the scroll bars will not appear.
		data.heightHint = 60;
		data.widthHint = 60;

		myOverviewTable.setLayoutData(data);
		// 7.4.09 for YONA : if you need more columns, just add the titles here.

		for (int i = 0; i < myOverviewTitles.length; i++) {
			TableColumn column = new TableColumn(myOverviewTable, SWT.NONE);
			column.setText(myOverviewTitles[i]);
			column.setAlignment(SWT.RIGHT);
		}

		myOverviewLabel = new Label(overviewContainer, SWT.NONE);

		return overviewContainer;
	}

	/**
	 * Fills the text fields in both tabs depending on the selected account.
	 * 
	 * @param actAccount
	 *            the account currently selected.
	 */
	private void actualizeAccountTexts(Account actAccount) {
		Account currentAccount = myAccountTable.get(myAccountCombo
				.getText());
		myCostsText.setText("");
		currentAccount.setTotalCosts(0);
		if (actAccount.getTanListNumber() == 0) {

			// No TAN-List created yet
			myTanListNumberText.setText(" ");
			myNumberOfTansText.setText(" ");
			myUnusedTansText.setText(" ");
			
			myUsedTansText.setText(" ");
			myCostsText.setText(" ");
		

			myBlockButton.setEnabled(false);
			myUnblockButton.setEnabled(false);

			
			myCostsPerFeatureTable.clearAll();
			
		} else {			

			myTanListNumberText.setText(actAccount.getTanListNumber()
					.toString());
			myNumberOfTansText.setText(actAccount.getNumberOfTans().toString());
			myUnusedTansText.setText(actAccount.getUnusedTans().toString());

			final Integer usedTans = actAccount.getNumberOfTans()
					- actAccount.getUnusedTans();
			myUsedTansText.setText(usedTans.toString());

			if (actAccount.isBlocked()) {
				myBlockButton.setEnabled(false);
				myUnblockButton.setEnabled(true);
			} else {
				myBlockButton.setEnabled(true);
				myUnblockButton.setEnabled(false);
			}

			// 7.4.09 for YONA: put count on the number of data base entries
			// and read them
			// int count = 128;
			myCostsPerFeatureTable.removeAll();
			
			List<String> featureUsageCostsList = currentAccount
					.getFeatureUsageCostsList();

			if (!featureUsageCostsList.toString().equals("[]") ) {
				for (String s : featureUsageCostsList) {
					String[] featureWalltime = s.split("::=");
					TableItem item = new TableItem(myCostsPerFeatureTable,
							SWT.NONE);
					// first item is the feature name
					item.setText(0, featureWalltime[0]);
					// second item is the usage
					BigDecimal cpuHours = new BigDecimal(Double
							.valueOf(featureWalltime[1]));
					cpuHours = cpuHours.setScale(2,
							BigDecimal.ROUND_HALF_UP);
					item.setText(1, String.valueOf(cpuHours));
					// third item is the cost per feature
					BigDecimal costsInEuro = new BigDecimal(Double
							.valueOf(featureWalltime[2]));
					costsInEuro = costsInEuro.setScale(2,
							BigDecimal.ROUND_HALF_UP);
					item.setText(2, String.valueOf(costsInEuro.doubleValue()));
					currentAccount.setTotalCosts(currentAccount.getTotalCosts()
							+ costsInEuro.doubleValue());
				}
				BigDecimal totalCosts = new BigDecimal(Double
						.valueOf(currentAccount
								.getTotalCosts()));
				totalCosts = totalCosts.setScale(2,
						BigDecimal.ROUND_HALF_UP);
				myCostsText.setText(String.valueOf(totalCosts));
			}
			
			else {
				/*myCostsPerFeatureTable.clearAll();
				TableItem item = new TableItem(myCostsPerFeatureTable, SWT.NONE);
				item.setText(0, "noFeature");
				item.setText(1, "");
				item.setText(2, "");
				currentAccount.setTotalCosts(0);*/
			}
			
				
			for (int i = 0; i < myCostsPerFeatureTitles.length; i++) {
				myCostsPerFeatureTable.getColumn(i).pack();
			}
			myCostsPerFeatureTable.redraw();

		}

		//
		// 7.4.09 for YONA: put count on the number of data base entries
		// and read them
		myOverviewTable.removeAll();
		double costs = 0;
		for (Enumeration<Account> e = myAccountTable.elements(); e
				.hasMoreElements();) {
			Account a = e.nextElement();
			TableItem item = new TableItem(myOverviewTable, SWT.NONE);
			item.setText(0, a.getAccountName());
			BigDecimal totalCosts = new BigDecimal(String.valueOf(a
					.getTotalCosts()));
			totalCosts = totalCosts.setScale(2, BigDecimal.ROUND_HALF_UP);
			item.setText(1, String.valueOf(totalCosts.doubleValue()));
			costs += totalCosts.doubleValue();
		}
		for (int i = 0; i < myOverviewTitles.length; i++) {
			myOverviewTable.getColumn(i).pack();
		}

		myOverviewTable.redraw();

		myOverviewLabel.setText("Total costs (€): " + costs);
		myOverviewLabel.redraw();

	}

	/*
	 * == Functional
	 * methods.====================================================
	 */

	/**
	 * Insert the accounts and information into a local Hashtable
	 */
	private boolean readAccounts() {

		String accountList = getLicenseAccounts();
		if(accountList.equals("NOBILLINGACCOUNT")){
			System.out.println("NO billingaccount");
				return false;
		}
		else{
			String[] accounts = accountList.split(";");
			if(! myAccountTable.isEmpty())
				myAccountTable.clear();
			
			Account account = null;
			for (String s : accounts) {

				Account accountInfo = getAccountInfo(s);
				account = new Account(s, accountInfo.getTanListNumber(),
						accountInfo.getNumberOfTans(), accountInfo.getUnusedTans(),
						accountInfo.getCPUHours(), accountInfo.isBlocked(),
						accountInfo.getFeatureUsageCostsList());
				myAccountTable.put(account.getAccountName(), account);
			}
			return true;
		}
	}

	/**
	 * Retrieves the information of an account from the server.
	 * 
	 * @param accountName
	 *            the name of the account
	 * @param responsible
	 *            the person responsible for this account, i.e. the owner
	 * @return a license account
	 */
	private Account getAccountInfo(String licenseAccountName) {
		Account accountInfoResponse = null;
		try {
			accountInfoResponse = myAccountClient.getAccountInfo(myBillingAccount,
					myPassword, licenseAccountName);
		} catch (RemoteException e) {
			logger.error("could not get account info - problem with the network connection ");
			logger.error("accountName is " + licenseAccountName);
			throw new RuntimeException(e);
		}
		return accountInfoResponse;
	}

	/**
	 * Retrieves all accounts that a user is responsible for from the Server.
	 * 
	 * @param responsible
	 *            the name of the owner of license accounts, i.e. the
	 *            responsible person
	 * @return Comma separated list of accounts
	 */
	private String getLicenseAccounts() {
		logger.info("attempting to get license accounts");
		String licenseAccounts = "";

		try {
			licenseAccounts = myAccountClient.getLicenseAccounts(myBillingAccount, myPassword);
			myEmail = myAccountClient.getEmail();
			myOrganization = myAccountClient.getOrganization();
			myUserName = myAccountClient.getResponsible();
			logger.info("retrieved license accounts for account " + myBillingAccount);
		} catch (RemoteException e) {
			logger.error("could not get license accounts - problem with the network connection ");
			throw new RuntimeException(e);
		} catch (Exception e) {
			System.out.println(e);
		}
		return licenseAccounts;
	}

	/**
	 * Creates a new account in the database on the serve via the account web
	 * service.
	 * 
	 * @param accountName
	 *            the name of the account to be created
	 * @return true if the web service was executed successfully
	 */
	private boolean createLicenseAccount(String licenseAccountName,
			String accountType) {

		boolean createSuccess = false;

		try {
			createSuccess = myAccountClient.createLicenseAccount(myBillingAccount,
					myPassword, licenseAccountName, accountType);

		} catch (RemoteException e) {
			logger.error("Could not create license account - problem with the network connection ");

		}

		return createSuccess;
	}

	/**
	 * Deletes an account in the database on the serve via the account web
	 * service.
	 * 
	 * @param accountName
	 *            the name of the account to be deleted
	 * @return true if the web service was executed successfully
	 */
	private boolean deleteLicenseAccount(String licenseAccountName) {
		boolean deleteSuccess = false;

		try {
			deleteSuccess = myAccountClient.deleteLicenseAccount(myBillingAccount,
					myPassword, licenseAccountName);

		} catch (RemoteException e) {
			logger.error("problem with the network connection "
					+ e.getMessage());
		}

		return deleteSuccess;
	}

	/**
	 * Creates a TANClient which forwards all requests to the TAN web service.
	 * 
	 * @return TAN client.
	 */
	private TANServiceClient createTANClient() {
		TANServiceStub localServiceStub = null;
		try {
			localServiceStub = new TANServiceStub(myProperties.getHostName()
					+ "/axis2/services/TANService");
		} catch (AxisFault e) {
			logger.error("TANServiceStub could not be generated "
					+ e.getMessage());
			throw new RuntimeException(e);
		}
		TANServiceClient client = new TANServiceClient(localServiceStub);
		return client;
	}

	/**
	 * Creates an AccountServiceClient which forwards all requests to the
	 * account web service.
	 * 
	 * @return Account client.
	 */
	private AccountServiceClient createAccountClient() {
		AccountServiceStub localServiceStub = null;
		try {
			localServiceStub = new AccountServiceStub(myProperties
					.getHostName()
					+ "/axis2/services/AccountService");
		} catch (AxisFault e) {
			logger.error("AccountServiceStub could not be generated "
					+ e.getMessage());
			throw new RuntimeException(e);
		}
		AccountServiceClient client = new AccountServiceClient(localServiceStub);
		return client;
	}

	/**
	 * Invokes the TAN client with the request to block the current TAN list.
	 * 
	 * @param account
	 *            the account name for which the TAN list shall be blocked.
	 * @return true if the operation was successful
	 */
	private boolean blockTANList(Account account) {
		boolean success = false;
		try {
			success = myTANClient.blockTANList(myBillingAccount, myPassword, account
					.getAccountName());

		} catch (RemoteException e) {
			logger.error("problem with the network connection "
					+ e.getMessage());
			throw new RuntimeException(e);
		}
		myAccountTable.get(account.getAccountName()).setIsBlocked(true);
		return success;
	}

	/**
	 * Invokes the TAN client with the request to unblock the TAN list.
	 * 
	 * @param account
	 *            the account name for which the TAN list shall be unblocked.
	 * @return true if the operation was successful
	 */
	private boolean unblockTANList(Account account) {
		boolean success = false;

		try {
			success = myTANClient.unBlockTANList(myBillingAccount, myPassword,
					account.getAccountName());

		} catch (RemoteException e) {
			logger.error("problem with the network connection "
					+ e.getMessage());
			throw new RuntimeException(e);
		}
		myAccountTable.get(account.getAccountName()).setIsBlocked(false);
		return success;

	}

	/**
	 * Invokes the TAN client with the request to create a new TAN list.
	 * 
	 * @param actualAccount
	 *            current account selected.
	 * @param numberOfTANs
	 *            how many TANs the new TAN list shall have.
	 */
	private void createTANList(Account actualAccount, Integer numberOfTANs) {
		actualAccount.setIsBlocked(false);
		actualAccount.increaseTanListNumber();
		actualAccount.setNumberOfTans(numberOfTANs);
		actualAccount.setUnusedTans(numberOfTANs);
		actualAccount.resetCPUHours();

		try {
			myTANClient.createTANList(myBillingAccount, myPassword, actualAccount
					.getAccountName(), numberOfTANs);

		} catch (RemoteException e) {
			logger.error("problem with the network connection "
					+ e.getMessage());
		}

		logger.debug("TODO Yona: generate " + numberOfTANs + " TANs !!!");
	}

	/**
	 * Logout the user from the system.
	 */
	private void logoutUser() {
		// TODO Yona: Benutzer abmelden !!!
		logger.debug("logout user!!!");
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		// initialise logger
		URL log4jconfig;
		try {
			String dataDir = System.getProperty("user.home");
			String logfile = "file:" + dataDir + java.io.File.separator  +"log4j.xml";
			log4jconfig = new URL(logfile);
			DOMConfigurator.configure(log4jconfig);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// Open the TAN- and Account- Management Application
		try {
			TANAndAccountManagementWindow window = new TANAndAccountManagementWindow();
			window.setBlockOnOpen(true);
			window.open();
		} catch (Exception e) {
			logger.error("TAN and account management window could not show up "
					+ e.getMessage());
		}
	}
}
